package cn.edu.dlmu.cogo.framework.context;

import cn.edu.dlmu.cogo.framework.annotation.*;
import cn.edu.dlmu.cogo.framework.utils.CogoClassUtil;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ReflectUtil;

import java.util.Arrays;

/**
 * @author yixi
 */
@Priority(Level.MAX)
public class ContextContainerAware implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {

        // 为Configuration注解标记的类中，被Bean注解标记的方法返回值注入容器
        CogoClassUtil.getClassesWithAnnotation(Configuration.class).forEach(aClass
                -> Arrays.asList(ReflectUtil.getMethods(aClass, method
                -> method.getAnnotation(Bean.class) != null)).forEach(method
                -> applicationContext.setBean((Object) ReflectUtil.invoke(ReflectUtil.newInstance(aClass), method), method.getAnnotation(Bean.class).value())));

        // 为Component注解标记的类注入容器
        CogoClassUtil.getClassesWithAnnotation(Component.class).forEach(aClass
                -> applicationContext.setBean(aClass, AnnotationUtil.getAnnotation(aClass, Component.class).value()));

        // 为Repository注解标记的类注入容器
        CogoClassUtil.getClassesWithAnnotation(Repository.class).forEach(aClass
                -> applicationContext.setBean(aClass, AnnotationUtil.getAnnotation(aClass, Repository.class).value()));

        // 为Service注解标记的类注入容器
        CogoClassUtil.getClassesWithAnnotation(Service.class).forEach(aClass
                -> applicationContext.setBean(aClass, AnnotationUtil.getAnnotation(aClass, Service.class).value()));

        // 为Controller注解标记的类注入容器
        CogoClassUtil.getClassesWithAnnotation(Controller.class).forEach(aClass
                -> applicationContext.setBean(aClass, AnnotationUtil.getAnnotation(aClass, Controller.class).value()));

        // 为Import注解标记的需要导入的类注入容器
        CogoClassUtil.getClassesWithAnnotation(Import.class, false).forEach(aClass -> {
            for (Class<?> importClass : aClass.getAnnotation(Import.class).value()) {
                applicationContext.setBean(importClass);
                Console.log("{} [CogoFramework]导入组件[{}]",Environment.getSystemTime(), importClass.getName());
            }
        });

        //自动装配
        applicationContext.getClasses().forEach(aClass -> new Refresher(aClass).refresh());
    }
}
